package com.qingzhuge.member.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.qingzhuge.common.Resources;
import com.qingzhuge.common.utils.HttpUtil;
import com.qingzhuge.member.entity.SysMemberThirdPartyAuth;
import com.qingzhuge.member.entity.SysMemberThirdPartyAuthConfig;
import com.qingzhuge.sys.service.ISysConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

import static com.qingzhuge.member.entity.SysMemberThirdPartyAuth.SYS_MEMBER_THIRDPARTY_AUTH;

/**
 * @author : zero.xiao
 * @description : 第三方登录辅助类
 * @date :2019-05-20 12:28
 * @modified :
 */
@Slf4j
public class ThirdPartyLoginHelper {
    @Resource
    private ISysConfigService configService;

    private SysMemberThirdPartyAuthConfig config;

    public SysMemberThirdPartyAuthConfig getConfig() {
        if (null == config){
            synchronized (this){
                if (null == config){
                    config = configService.getConfigObject(SYS_MEMBER_THIRDPARTY_AUTH,SysMemberThirdPartyAuthConfig.class);
                }
            }
        }
        return config;
    }

    /**
     * 获取QQ用户信息
     */
    public SysMemberThirdPartyAuth getQQUserinfo(String token, String openid) {
        SysMemberThirdPartyAuth user = new SysMemberThirdPartyAuth();
        String url = this.getConfig().getGetUserInfoURL();
        url = url + "?format=json&access_token=" + token + "&oauth_consumer_key="
                + this.getConfig().getAppId() + "&openid=" + openid;
        String res = HttpUtil.get(url);
        JSONObject json = JSON.parseObject(res);
        if (json.getIntValue("ret") == 0) {
            user.setNickName(json.getString("nickname"));
            String img = json.getString("figureurl_qq_2");
            if (img == null || "".equals(img)) {
                img = json.getString("figureurl_qq_1");
            }
            user.setAvatarUrl(img);
            String sex = json.getString("gender");
            if ("女".equals(sex)) {
                user.setGender(0L);
            } else {
                user.setGender(1L);
            }
        } else {
            throw new IllegalArgumentException(json.getString("msg"));
        }
        return user;
    }

    /** 获取微信用户信息 */
    public SysMemberThirdPartyAuth getWxUserinfo(String token, String openid) {
        SysMemberThirdPartyAuth user = new SysMemberThirdPartyAuth();
        String url = this.getConfig().getGetUserInfoURL();
        url = url + "?access_token=" + token + "&openid=" + openid;
        String res = HttpUtil.get(url);
        JSONObject json = JSON.parseObject(res);
        if (json.getString("errcode") == null) {
            user.setNickName(json.getString("nickname"));
            String img = json.getString("headimgurl");
            if (img != null && !"".equals(img)) {
                user.setAvatarUrl(img);
            }
            String sex = json.getString("sex");
            if ("0".equals(sex)) {
                user.setGender(0L);
            } else {
                user.setGender(1L);
            }
        } else {
            throw new IllegalArgumentException(json.getString("errmsg"));
        }
        return user;
    }

    /** 获取微信小程序openid */
    public String getWxAppOpenid(String code) {
        String url = this.getConfig().getJscode2session();
        Map<String,String> params = Maps.newHashMap();
        params.put("appid", this.getConfig().getAppId());
        params.put("secret", this.getConfig().getAppSecret());
        params.put("js_code", code);
        params.put("grant_type", "authorization_code");
        String res = HttpUtil.post(url, params);
        JSONObject json = JSON.parseObject(res);
        if (json.getString("errcode") == null || "0".equals(json.getString("errcode"))) {
            return json.getString("openid");
        } else {
            throw new IllegalArgumentException(json.getString("errmsg"));
        }
    }

    /**
     * 获取新浪用户信息
     */
    public SysMemberThirdPartyAuth getSinaUserinfo(String token, String uid) {
        SysMemberThirdPartyAuth user = new SysMemberThirdPartyAuth();
        String url = this.getConfig().getGetUserInfoURL();
        url = url + "?access_token=" + token + "&uid=" + uid;
        String res = HttpUtil.get(url);
        JSONObject json = JSON.parseObject(res);
        String name = json.getString("name");
        String nickName = StringUtils.isBlank(json.getString("screen_name")) ? name : json.getString("screen_name");
        user.setAvatarUrl(json.getString("avatar_large"));
        user.setNickName(nickName);
        if ("f".equals(json.getString("gender"))) {
            user.setGender(0L);
        } else {
            user.setGender(1L);
        }
        user.setToken(token);
        user.setOpenId(uid);
        user.setProvider("sina");
        return user;
    }

    /**
     * 获取QQ的认证token和用户OpenID
     */
    public Map<String, String> getQQTokenAndOpenid(String code, String host) {
        Map<String, String> map = new HashMap<>();
        // 获取令牌
        String tokenUrl = this.getConfig().getAccessTokenURL();
        tokenUrl = tokenUrl + "?grant_type=authorization_code&client_id=" + this.getConfig().getAppId()
                + "&client_secret=" + this.getConfig().getAppKey() + "&code=" + code
                + "&redirect_uri=http://" + host + this.config.getRedirectUrl();
        String tokenRes = HttpUtil.get(tokenUrl);
        if (tokenRes != null && tokenRes.contains("access_token")) {
            Map<String, String> tokenMap = toMap(tokenRes);
            map.put("access_token", tokenMap.get("access_token"));
            // 获取QQ用户的唯一标识openID
            String openIdUrl = this.getConfig().getGetOpenIDURL();
            openIdUrl = openIdUrl + "?access_token=" + tokenMap.get("access_token");
            String openIdRes = HttpUtil.get(openIdUrl);
            int i = openIdRes.indexOf("(");
            int j = openIdRes.indexOf(")");
            openIdRes = openIdRes.substring(i + 1, j);
            JSONObject openidObj = JSON.parseObject(openIdRes);
            map.put("openId", openidObj.getString("openid"));
        } else {
            throw new IllegalArgumentException(Resources.getMessage("THIRDPARTY.LOGIN.NOTOKEN", "QQ"));
        }
        return map;
    }

    /**
     * 获取微信的认证token和用户OpenID
     */
    public Map<String, String> getWxTokenAndOpenid(String code, String host) {
        Map<String, String> map = new HashMap<>();
        // 获取令牌
        String tokenUrl = this.getConfig().getAccessTokenURL();
        tokenUrl = tokenUrl + "?appid=" + this.getConfig().getAppId() + "&secret="
                + this.getConfig().getAppKey() + "&code=" + code + "&grant_type=authorization_code";
        String tokenRes = HttpUtil.get(tokenUrl);
        if (tokenRes != null && tokenRes.contains("access_token")) {
            Map<String, String> tokenMap = toMap(tokenRes);
            map.put("access_token", tokenMap.get("access_token"));
            // 获取微信用户的唯一标识openid
            map.put("openId", tokenMap.get("openid"));
        } else {
            throw new IllegalArgumentException(Resources.getMessage("THIRDPARTY.LOGIN.NOTOKEN", "weixin"));
        }
        return map;
    }

    /**
     * 获取新浪登录认证token和用户id
     */
    public JSONObject getSinaTokenAndUid(String code, String host) {
        JSONObject json = null;
        try {
            // 获取令牌
            String tokenUrl = this.getConfig().getAccessTokenURL();
            Map<String,String> params = Maps.newHashMap();
            params.put("client_id",this.getConfig().getAppId());
            params.put("client_secret",this.getConfig().getAppKey());
            params.put("grant_type","authorization_code");
            params.put("redirect_uri","http://" + host + this.getConfig().getRedirectUrl());
            params.put("code",code);
            String tokenRes = HttpUtil.post(tokenUrl, params);
            // String tokenRes = httpClient(tokenUrl);
            // {"access_token":"2.00AvYzKGWraycB344b3eb242NUbiQB","remind_in":"157679999","expires_in":157679999,"uid":"5659232590"}
            if (tokenRes != null && tokenRes.contains("access_token")) {
                json = JSON.parseObject(tokenRes);
            } else {
                throw new IllegalArgumentException(Resources.getMessage("THIRDPARTY.LOGIN.NOTOKEN", "sina"));
            }
        } catch (Exception e) {
            log.error("", e);
        }
        return json;
    }

    /**
     * 将格式为s1&s2&s3...的字符串转化成Map集合
     */
    private Map<String, String> toMap(String str) {
        Map<String, String> map = new HashMap<>(8);
        String[] strs = str.split("&");
        for (String str2 : strs) {
            String[] ss = str2.split("=");
            map.put(ss[0], ss[1]);
        }
        return map;
    }
}
